package com.yikome.delivery.schedule;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.yikome.config.ApiResult;
import com.yikome.delivery.entity.Delivery;
import com.yikome.delivery.entity.DeliveryDetails;
import com.yikome.delivery.enums.DeliveryStatus;
import com.yikome.delivery.repository.DeliveryRepository;
import com.yikome.delivery.schedule.dto.InvoiceCreateRequest;
import com.yikome.delivery.schedule.dto.InvoiceDetailsCreateRequest;
import com.yikome.storehouse.entity.Storehouse;
import com.yikome.storehouse.repository.StorehouseRepository;

import cn.hutool.core.util.StrUtil;

@Component
public class AsyncDeliverySchedule {

	@Autowired
	private DeliveryRepository deliveryRepository ; 
	
	@Autowired
	private StorehouseRepository storehouseRepository ; 
	
	@Autowired
	private RestTemplate restTemplate ; 
	
	@Value("${schedule.async.salt}")
	private String salt ; 
	@Value("${schedule.async.delivery.basicUrl}")
	private String basicUrl ; 
	
	/******************************************************************* 新增 **************************************************************************/
	
	@Transactional
	public void asyncDeliveryCreate(Delivery delivery, List<DeliveryDetails> deliveryDetails) {
		
		Storehouse storehouse = storehouseRepository.findStorehouse(delivery.getStorehouseId());
		Preconditions.checkArgument(storehouse != null, "仓库不存在");
		Preconditions.checkArgument(StrUtil.isNotBlank(storehouse.getRemoteStorehouseCode()), "远程仓库编码不存在");
		
		List<InvoiceCreateRequest> invoiceCreateRequests = new ArrayList<>();
		
		InvoiceCreateRequest invoiceCreateRequest = new InvoiceCreateRequest();
		invoiceCreateRequest.setStorehouseCode(storehouse.getRemoteStorehouseCode());
		invoiceCreateRequest.setSourceCode(delivery.getDeliveryCode());
		invoiceCreateRequest.setInvoicePrice(delivery.getDeliveryPrice());
		invoiceCreateRequest.setComments(delivery.getRemark());
		invoiceCreateRequest.setConsignee(delivery.getConsignee());
		invoiceCreateRequest.setTel(delivery.getTel());
		invoiceCreateRequest.setContry(delivery.getContry());
		invoiceCreateRequest.setProvince(delivery.getProvince());
		invoiceCreateRequest.setCity(delivery.getCity());
		invoiceCreateRequest.setDistrict(delivery.getDistrict());
		invoiceCreateRequest.setDetail(delivery.getDetail());
		invoiceCreateRequest.setPostCode(delivery.getZipCode());
		invoiceCreateRequest.setEmail(delivery.getEmail());
		invoiceCreateRequest.setCurrency(delivery.getCurrency());
		
		List<InvoiceDetailsCreateRequest> invoiceDetailsCreateRequests = new ArrayList<>();
		for (DeliveryDetails details : deliveryDetails) {
			InvoiceDetailsCreateRequest invoiceDetailsCreateRequest = new InvoiceDetailsCreateRequest();
			invoiceDetailsCreateRequest.setBarcode(details.getProductSkuBarcode());
			invoiceDetailsCreateRequest.setDeclaredName(details.getProductTitle());
			invoiceDetailsCreateRequest.setDeclaredSpecification(details.getProductSkuName());
			invoiceDetailsCreateRequest.setQuantity(details.getQuantity());
			invoiceDetailsCreateRequests.add(invoiceDetailsCreateRequest);
		}
		
		invoiceCreateRequest.setItems(invoiceDetailsCreateRequests);
		
		invoiceCreateRequests.add(invoiceCreateRequest);
		
		HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("salt", salt);
        HttpEntity<List<InvoiceCreateRequest>> entity = new HttpEntity<>(invoiceCreateRequests, headers);
		
		ResponseEntity<ApiResult> exchange = restTemplate.exchange(basicUrl + "create" , HttpMethod.POST, entity, ApiResult.class);
		
		Preconditions.checkArgument(HttpStatus.OK == exchange.getStatusCode(), "远程操作不可用...");
        
		if(exchange.getBody().getCode() != ApiResult.CODE_SUCCESS) {
			throw new IllegalArgumentException("远程操作失败.原因: " + exchange.getBody().getMessage());
		}
		
		List<Map<String , Object>> lists = (List<Map<String, Object>>) exchange.getBody().getDatas();
		
		if(!lists.isEmpty()) {
			throw new IllegalArgumentException("远程操作失败.原因: " + lists.get(0).get("errorMsg"));
		}
		
		delivery.setStatus(DeliveryStatus.DELIVERY_ASYNC.getStatus());
		deliveryRepository.save(delivery);
		
	}
	
	/******************************************************************* 删除 **************************************************************************/
	
	@Transactional
	public void asyncDeliveryDelete(String deliveryCode) {

		HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("salt", salt);
        HttpEntity<List<Object>> httpEntity = new HttpEntity<>(ImmutableList.of(deliveryCode) , headers);
        
        ResponseEntity<ApiResult> exchange = restTemplate.exchange(basicUrl + "delete" , HttpMethod.DELETE, httpEntity, ApiResult.class);
        
        Preconditions.checkArgument(HttpStatus.OK == exchange.getStatusCode(), "远程仓库请求不可用...");
        
        Preconditions.checkArgument((exchange.getBody().getCode() == ApiResult.CODE_SUCCESS), "远程删除失败.原因: " + exchange.getBody().getMessage());
	}
}
